home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xmlink / MlinkU.c < prev    next >
C/C++ Source or Header  |  1996-02-05  |  6KB  |  252 lines

  1. /*
  2. # X-BASED MISSING LINK(tm)
  3. #
  4. #  MlinkU.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /* Undo algorithm */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <X11/IntrinsicP.h>
  31. #include <X11/Intrinsic.h>
  32. #include <X11/StringDefs.h>
  33. #include <X11/CoreP.h>
  34. #include "MlinkP.h"
  35.  
  36. typedef struct _MoveRecord
  37. {
  38.   /* int direction, control; */
  39.   unsigned char packed; /* This makes assumptions on the data. */
  40.   int tile; /* Do not make assumptions on this one. */
  41. } MoveRecord;
  42.  
  43. typedef struct _MoveStack
  44. {
  45.   MoveRecord move;
  46.   struct _MoveStack *previous, *next;
  47. } MoveStack;
  48.  
  49. static MoveStack *currMove, *lastMove, *firstMove;
  50. static int count;
  51. static int startSpace;
  52. int *startPosition = NULL;
  53.  
  54. static void InitStack();
  55. static void PushStack();
  56. static void PopStack();
  57. static int EmptyStack();
  58. static void FlushStack();
  59.  
  60. static void InitStack()
  61. {
  62.   if (!(lastMove = (MoveStack *) malloc(sizeof(MoveStack))))
  63.     XtError("Not enough memory, exiting.");
  64.   if (!(firstMove = (MoveStack *) malloc(sizeof(MoveStack))))
  65.     XtError("Not enough memory, exiting.");
  66.   firstMove->previous = lastMove->next = NULL;
  67.   firstMove->next = lastMove;
  68.   lastMove->previous = firstMove;
  69.   count = 0;
  70. }
  71.  
  72. static void PushStack(move)
  73.   MoveRecord move;
  74. {
  75.   if (!(currMove = (MoveStack *) malloc(sizeof(MoveStack))))
  76.     XtError("Not enough memory, exiting.");
  77.   lastMove->previous->next = currMove;
  78.   currMove->previous = lastMove->previous;
  79.   currMove->next = lastMove;
  80.   lastMove->previous = currMove;
  81.   currMove->move = move;
  82.   count++;
  83. }
  84.  
  85. static void PopStack(move)
  86.   MoveRecord *move;
  87. {
  88.   *move = lastMove->previous->move;
  89.   currMove = lastMove->previous;
  90.   lastMove->previous->previous->next = lastMove;
  91.   lastMove->previous = lastMove->previous->previous;
  92.   (void) free((void *) currMove);
  93.   count--;
  94. }
  95.  
  96. static int EmptyStack()
  97. {
  98.   return (lastMove->previous == firstMove);
  99. }
  100.  
  101. static void FlushStack()
  102. {
  103.   while (lastMove->previous != firstMove) {
  104.     currMove = lastMove->previous;
  105.     lastMove->previous->previous->next = lastMove;
  106.     lastMove->previous = lastMove->previous->previous;
  107.     (void) free((void *) currMove);
  108.   }
  109.   count = 0;
  110. }
  111.  
  112. /**********************************/
  113.  
  114. void InitMoves()
  115. {
  116.   InitStack();
  117. }
  118.  
  119. static void WriteMove(move, direction, tile, control)
  120.   MoveRecord *move;
  121.   int direction, tile, control;
  122. {
  123.   /* move->direction = direction; move->control = control; */
  124.   move->packed = ((control & 0xF) << 4) + (direction & 0xF);
  125.   move->tile = tile;
  126. }
  127.  
  128. static void ReadMove(direction, tile, control, move)
  129.   int *direction, *tile, *control;
  130.   MoveRecord move;
  131. {
  132.   /* *direction = move.direction; *control = move.control; */
  133.   *direction = move.packed & 0xF;
  134.   *control = (move.packed >> 4) & 0xF;
  135.   *tile = move.tile;
  136. }
  137.  
  138. void PutMove(direction, tile, control)
  139.   int direction, tile, control;
  140. {
  141.   MoveRecord move;
  142.  
  143.   WriteMove(&move, direction, tile, control);
  144.   PushStack(move);
  145. }
  146.  
  147. void GetMove(direction, tile, control)
  148.   int *direction, *tile, *control;
  149. {
  150.   MoveRecord move;
  151.  
  152.   PopStack(&move);
  153.   ReadMove(direction, tile, control, move);
  154. }
  155.  
  156. int MadeMoves()
  157. {
  158.   return !EmptyStack();
  159. }
  160.  
  161. void FlushMoves(w)
  162.   MlinkWidget w;
  163. {
  164.   int i;
  165.  
  166.   FlushStack();
  167.   startSpace = w->mlink.spacePosition;
  168.   startPosition[w->mlink.tileFaces - 1] = 0;
  169.   for (i = 0; i < w->mlink.tileFaces; i++)
  170.     startPosition[i] = w->mlink.tileOfPosition[i];
  171. }
  172.  
  173. int NumMoves()
  174. {
  175.   return count;
  176. }
  177.  
  178. void ScanMoves(fp, w, moves)
  179.   FILE *fp;
  180.   MlinkWidget w;
  181.   int moves;
  182. {
  183.   int direction, tile, shift, l;
  184.   char c;
  185.  
  186.   for (l = 0; l < moves; l++) {
  187.     while ((c = getc(fp)) != EOF && c != SYMBOL);
  188.     (void) fscanf(fp, "%d %d %d", &direction, &tile, &shift);
  189.     if (!MoveMlink(w, direction, tile, shift))
  190.       (void) fprintf(fp,
  191.         "%d move in direction %d, tile %d, shift %d, can not be made.",
  192.         l, direction, tile, shift);
  193.   }
  194. }
  195.  
  196. void PrintMoves(fp)
  197.   FILE *fp;
  198. {
  199.   int direction, tile, control, counter = 0;
  200.  
  201.   currMove = firstMove->next;
  202.   (void) fprintf(fp, "moves\tdir\ttile\tshift\n"); 
  203.   while (currMove != lastMove) {
  204.     ReadMove(&direction, &tile, &control, currMove->move);
  205.     (void) fprintf(fp, "%d%c\t%d\t%d\t%d\n",
  206.       ++counter, SYMBOL, direction, tile, control); 
  207.     currMove = currMove->next;
  208.   }
  209. }
  210.  
  211. void ScanStartPosition(fp, w)       
  212.   FILE *fp;
  213.   MlinkWidget w;
  214. {
  215.   int i, num;
  216.   char c;
  217.  
  218.   while ((c = getc(fp)) != EOF && c != SYMBOL);
  219.   for (i = 0; i < w->mlink.tileFaces; i++) {
  220.     (void) fscanf(fp, "%d ", &num);
  221.     startPosition[i] = num;
  222.     if (!num)
  223.       startSpace = i;
  224.   }
  225. }
  226.  
  227. void PrintStartPosition(fp, w)       
  228.   FILE *fp;
  229.   MlinkWidget w;
  230. {
  231.   int i;
  232.  
  233.   (void) fprintf(fp, "\nstartingPosition%c\n", SYMBOL);
  234.   for (i = 0; i < w->mlink.tileFaces; i++) {
  235.     (void) fprintf(fp, "%3d ", startPosition[i]);
  236.     if (!((i + 1) % w->mlink.tiles))
  237.       (void) fprintf(fp, "\n");
  238.   }
  239.   (void) fprintf(fp, "\n");
  240. }
  241.  
  242. void SetStartPosition(w)       
  243.   MlinkWidget w;
  244. {
  245.   int i;
  246.  
  247.   w->mlink.spacePosition = startSpace;
  248.   for (i = 0; i < w->mlink.tileFaces; i++)
  249.     w->mlink.tileOfPosition[i] = startPosition[i];
  250.   DrawAllTiles(w, w->mlink.tileGC, w->mlink.borderGC);
  251. }
  252.